package org.example.filter;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.example.common.BodyReaderHttpServletRequestWrapper;
import org.example.common.HygResponse;
import org.example.config.WebConfig;
import org.example.enums.DomainToSignatureEnum;
import org.example.enums.RequestMethodEunm;
import org.example.utils.IpUtil;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

/**
 * @author liyishan
 * @date 2023/4/18 15:38
 */
@Slf4j
@WebFilter(urlPatterns = "/*")
public class MyWebFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
        log.info("过滤器初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        long start = System.currentTimeMillis();
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String ip = IpUtil.getRealIp(request);
        String uri = request.getRequestURI();
        StringBuffer url = request.getRequestURL();
        BodyReaderHttpServletRequestWrapper requestWrapper = new BodyReaderHttpServletRequestWrapper(request);
        PrintWriter writer;
        Map<String, String[]> parameterMap = request.getParameterMap();
        if (parameterMap.containsKey("passWord")) {
            parameterMap.put("passWord", new String[]{"******"});
        }
        String accessParam = JSON.toJSONString(parameterMap);
        if (StringUtils.isEmpty(accessParam) || "{}".equals(accessParam)) {
            accessParam = requestWrapper.getBodyS();
        }

        //白名单(不需要鉴权 不需要跨域处理)

        if (WebConfig.match(WebConfig.WHITE_URL_01, uri)) {
            log.info("* white url *:\n\tip:{}, url:{}, uri:{};\n\tform param:{}.", ip, url, uri, accessParam);
            filterChain.doFilter(requestWrapper, response);
            return;
        }


        //跨域处理
        String origin = request.getHeader("Origin");
        if (!StringUtils.isEmpty(origin)) {
            if (origin.contains("hvyosv.com") || origin.contains("localhost") || origin.contains("127.0.0.1")
                    || origin.contains(DomainToSignatureEnum.HVYOGO.getDomain())
                    || origin.contains(DomainToSignatureEnum.GXCARDS.getDomain())
                    || origin.contains(DomainToSignatureEnum.HIQIFU.getDomain())
                    || origin.contains(DomainToSignatureEnum.HVCIN.getDomain())
                    || origin.contains(DomainToSignatureEnum.HVYOGO_CN.getDomain())
                    || origin.contains(DomainToSignatureEnum.HENG_YANG_HIFU_COM.getDomain())
                    || origin.contains(DomainToSignatureEnum.HNHIFU_COM.getDomain())
                    || origin.contains(DomainToSignatureEnum.HVYOGO_NET.getDomain())) {
                response.setContentType("application/json; charset=utf-8");
                response.setHeader("Access-Control-Allow-Credentials", "true");
                response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
                response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
                response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE");
                response.setHeader("Access-Control-Max-Age", "3600");
                response.setHeader("Access-Control-Allow-Origin", origin);
            }
        }
        //健康检测;
        if ("/".equals(uri)) {
            //log.info("* alive check * ip: {} url: {} \n", ip, url);
            response.setContentType("application/json; charset=utf-8");
            writer = response.getWriter();
            writer.write(JSON.toJSONString(HygResponse.Success()));
            writer.flush();
            writer.close();
            return;
        }
        if (RequestMethodEunm.OPTIONS.getMethod().equals(request.getMethod())) {
            //浏览器对复杂跨域请求的预请求，试探服务器响应是否正确，跳过
            filterChain.doFilter(requestWrapper, response);
            return;
        }

        //白名单(不需要鉴权)
        if (WebConfig.match(WebConfig.WHITE_URL_02, uri)) {
            log.info("* white url 02 * ip:{}, url:{}, uri:{}\n", ip, url, uri);
            filterChain.doFilter(requestWrapper, response);
            return;
        }

        //记录请求信息
        log.info("请求info: ip:{},url:{},uri:{},param:{}", ip, url, uri, accessParam);
        filterChain.doFilter(requestWrapper, response);
        //访问结束
        log.info("请求结束: ip:{}, url:{}, uri:{}, 耗时:{}ms.", ip, url, uri, System.currentTimeMillis() - start);
    }


    @Override
    public void destroy() {
        log.info("过滤器已销毁");
    }

}
